/** 
 * @(#)Verbindung.java
 */

/**
 * @author Robert Denda&Didier Gutacker
 * @version 1.0
 * @see Link
 * @see LinkRIP 
 * @see ArchitectureComponent
 *
 * original author Robert Denda, changes made by Didier Gutacker
 */

import java.util.Vector;
import java.awt.*;

public abstract class Verbindung extends ArchitectureComponent {
  int weight = 32;		
  Vector travellingPackets;
  Vector tiebreaknode;
  Vector tiebreaklink;

  int timestamp = 0;
  int currentTimestamp = 0;
  int x1, x2, y1, y2, textX, textY, textHeight, textWidth;
  int inPaint = 0;
  int nodeWidth, nodeHeight;

  boolean initialized = false;	// initialization flag
  boolean setWeightRequest = false; // flag set if this Link's weight shall be reset
  public  boolean tiebreak=false;

  FontMetrics fontMetrics;

  Lock addPacketLock;
  Lock paintLock;
  Lock weightGuard;

  public Verbindung( int id, SimulationObject net, Graphics gc  ) {
    super( id, net, gc );
    if ( net.isFinished() ) {
      return;
    } // if
    travellingPackets = new Vector();
    tiebreaklink      = new Vector();
    tiebreaknode      = new Vector();
    addPacketLock = new Lock();
    paintLock = new Lock();
    weightGuard = new Lock();
    fontMetrics = gc.getFontMetrics();
    textHeight = fontMetrics.getAscent() + fontMetrics.getDescent() + 1;
  } // Link.Verbindung

  public boolean atLocation( int x, int y ) {
    if ( super.atLocation( x, y ) ) {
      if ( textX <= x && x <= ( textX + textWidth ) && ( textY - textHeight ) <= y && y <= textY ) {
	return true;
      } else { 
	double xmin = (double) Math.min( x1, x2 );
	double ymin = (double) Math.min( y1, y2 );
	double xmax = (double) Math.max( x1, x2 );
	double ymax = (double) Math.max( y1, y2 );
	if ( ( xmin <= (double) x ) && ( (double) x <= xmax ) 
	     && ( ymin <= (double) y ) && ( (double) y <= ymax ) ) {
	  double y0;
	  if ( xmin == xmax ) {
	    return true;
	  } // if
	  if ( ( xmin == x1 && ymin == y1 ) || ( xmin == x2 && ymin == y2 ) ) {
	    y0 = ymin + ( ( ymax - ymin ) * ( ((double) x) - xmin ) / ( xmax - xmin ) );
	  } else {
	    y0 = ymax - ( ( ymax - ymin ) * ( ((double) x) - xmin ) / ( xmax - xmin ) ); 
	  } // if
	  if ( ( y0 - 2 ) <= ( (double) y ) && ( y0 + 2 ) >= ( (double) y ) ) {
	    return true;
	  } else {
	    return false;
	  } // if
	} else {
	  return false;
	} // if
      } // if
    } else {
      return false;
    } // if
  } // Verbindung.atLocation

  public void acquireLocks() {
    super.acquireLocks();
    addPacketLock.acquire();
    paintLock.acquire();
    weightGuard.acquire();
  } // Verbindung.acquireLocks

  public void releaseLocks() {
    weightGuard.release();
    paintLock.release();
    addPacketLock.release();
    super.releaseLocks();
  } // Verbindung.releaseLocks

  public void setWeight() {
    mark();
    setWeightRequest = true;
    wakeUp();		// trick:  use link's own thread to create dialogue
  } // Verbindung.setWeight

  String getLabel() {
    return ( text.linkTitleText.substring(0, 1) + id + ": " + weight ) ;
  } // Verbindung.getLabel

  public void addPacket( Packet p ) {
    if ( travellingPackets != null ) {
      addPacketLock.acquire();
      travellingPackets.addElement( p );
      addPacketLock.release();
      timestamp %= 10000;		// should be enough 
      paintRequest();
    } // if
  } // Verbindung.addPacket

  public int getWeight() {
    weightGuard.acquire();
    int returnValue = weight;
    weightGuard.release();
    return returnValue;
  } // Verbindung.getWeight

} // Verbindung




